package jdk7_new_features;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 * @author 半叶禅
 * 主要是jdk7中的新特性 
 *
 */
public class NewFeaturesDemo {

	public static void main(String[] args) {
		switch4String();
	}
	/**
	 * switch 可以使用字符串
	 *   1.7之前的switch语句中的条件表达式的类型     支持 整数类型兼容的类型,包括基本类型 char,byte,short,int 以及基本类型对应的封装类,还有枚举类型
	 *   	1.7开始支持字符串,即String
	 *   	实现原理： 这个新特性是在编译器这个层次上实现的,而在java虚拟机和字节代码这个层次上，还是只支持在switch 语句中使用与整数类型兼容的类型。在编译的过程
	 *   		   编译器会根据源代码的含义来进行转换，将字符串转换成与整数类型兼容的格式,即使用字符串的哈希值作为switch语句的表达式的值
	 *   		建议：在使用字符串的时候,如果能使用枚举代替，还是尽量使用枚举
	 */
	public static void switch4String() {
		
		//1.7 之前
		int testInt = 2;
		switch (testInt) {
			case 1:
				System.out.println("1");
				break;
			case 2 :
				System.out.println("2");
				break;
			case 3 :
				System.out.println("3");
				break;
			default:
				System.out.println("4");
		}
		
		//1.7 
		String testStr = "xiaoming";
		switch (testStr) {
			case "xiaohua":
				System.out.println("xiaohua");
				break;
			case "xiaoming" :
				System.out.println("xiaoming");
				break;
			default:
				System.out.println("nobody");
				break;
		}

	}
	
	
	/**
	 * 数值字面量的改进
	 * 	1.支持 二进制整数字面量    	1.7之前只支持十进制,八进制,十六进制
	 *  2.在数值字面量中使用下划线 
	 */
	
	public void numberDisplay() {
		//1.7之前
		int a = 10;    //十进制
		int b = 056;   //八进制
		int c = 0x12;  //十六进制
		
		int d = 15000000;
		
		//1.7
		int e = 0b1010;
		int f = 150_000_000;
		
		/*float pi1 = 3_.1415F;      // 无效; 不能和小数点相邻
		float pi2 = 3._1415F;      // 无效; 不能和小数点相邻
		long socialSecurityNumber1 = 999_99_9999_L;         // 无效; 不能放在L后缀之前

		int x1 = _52;              // 无效；这是个标识符，不是数字的字面量
		int x2 = 5_2;              // OK
		int x3 = 52_;              // 无效; 不能放在数字的结尾
		int x4 = 5_______2;        // OK

		int x5 = 0_x52;            // 无效; 不能放在 0x 中间 
		int x6 = 0x_52;            // 无效; 不能放在数字的开头
		int x7 = 0x5_2;            // OK
		int x8 = 0x52_;            // 无效; 不能放在数字的结尾

		int x9 = 0_52;             // OK 
		int x10 = 05_2;            // OK
		int x11 = 052_;            // Invalid; 不能放在数字的结尾
		*/		
		
	}
	
	/**
	 * 优化的异常处理
	 * 	1.可以同时捕捉多个异常
	 *  2.对重新抛出异常的高级类型检查  即针对 异常消失情况的处理
	 *  	异常消失： 如果在try语句块中抛出了异常，在控制权转移到 调用栈上一层代码之前，finally语句块中的语句也会执行。但是finally语句块在执行的过程中，也可能会抛出异常。
	 * 			         如果finally语句块也抛出了异常，那么这个异常会往上传递，而之前try语句块中的那个异常就丢失了
	 */
	public void exceptionDemo(String fromPath) {
		
		//1.7之前
		InputStream input = null;
		try{
			input = new FileInputStream(fromPath);
		}catch (IOException ex) {
			ex.printStackTrace();
		}catch(NullPointerException e){
			throw e;
		}
		
		//改进后
		InputStream input2 = null;
		try{
			input2 = new FileInputStream(fromPath);
		}catch (IOException|NullPointerException ex) {
			ex.printStackTrace();
		}
		
	}
	
	/**
	 * 异常消失： 如果在try语句块中抛出了异常，在控制权转移到 调用栈上一层代码之前，finally语句块中的语句也会执行。但是finally语句块在执行的过程中，也可能会抛出异常。
	 * 			         如果finally语句块也抛出了异常，那么这个异常会往上传递，而之前try语句块中的那个异常就丢失了
	 */
	public class DisappearedException {
	    public void show(){
	        try {
	              Integer.parseInt("Hello");
	        }catch (NumberFormatException nfe) {
	              throw nfe;
	        } finally {
	              try {
	                  int result = 2 / 0;
	              } catch (ArithmeticException ae) {
	                  throw ae;
	              }
	        }
	    }
	}
	
	//1.7 改进后
	public class ReadFile {
	    public void read(String filename) throws IOException {
	        FileInputStream input = null;
	        IOException readException = null;
	        try {
	              input = new FileInputStream(filename);
	        } catch (IOException ex) {
	              readException = ex;
	        } finally {
	              if (input != null) {
	                  try {
	                      input.close();
	                  } catch (IOException ex) {
	                      if (readException != null) {
	                          readException.addSuppressed(ex);//******不同之处*****
	                      }
	                      else {
	                          readException = ex;
	                      }
	                  }
	              }
	              if (readException != null) {
	                  throw readException;
	              }
	        }
	    }
	}
	
	
	/**
	 * 1.7 添加了新的资源管理方式  用来自动释放资源  try-with-resource 
	 * @param fromPath
	 * @param toPath
	 * @throws IOException
	 */
	
	//try-with-resource 
		public void copyFile(String fromPath,String toPath) throws IOException {
			try(InputStream input = new FileInputStream(fromPath);
				OutputStream output = new FileOutputStream(toPath);
			   ){
				byte[] buffer = new byte[1024];
				int len = -1;
				while((len = input.read(buffer)) != -1 ) {
					output.write(buffer, 0, len);
				}
			}
		}
		
		
		//try-catch-finally
		public void copyFile2(String fromPath,String toPath) throws IOException {
			InputStream input = null;
			OutputStream output = null;
			try{
				input = new FileInputStream(fromPath);
				output = new FileOutputStream(toPath);
				byte[] buffer = new byte[1024];
				int len = -1;
				while((len = input.read(buffer)) != -1 ) {
					output.write(buffer, 0, len);
					}
			}catch (Exception e) {
				// TODO: handle exception
			}finally {
				input.close();
				output.close();
			}
		}
	
	/**
	 * 变长度的参数
	 */
	
		
		
		

	//脚本引擎 javaScript
	public static void greet() throws ScriptException {
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine engine = manager.getEngineByName("JavaScript");
		if(engine != null) {
			engine.eval("pri('hello world !!');");
		}
	}	
}
	

